/* Time-stamp: <2010-09-22 11:58:22 xinhaoyuan> */
/* Head file for memory arrangment of EKOS */
/* This is modified from original file of JOS */

#ifndef _EKOS_MEMLAYOUT_H_
#define _EKOS_MEMLAYOUT_H_

/* see documents/MEMLAYOUT for description */

#ifndef __ASSEMBLER__
#include "types.h"
#include "mmu.h"
#endif /* not __ASSEMBLER__ */

// Global Descriptor
#define GD_KERN_TEXT    0x08	// kernel text
#define GD_KERN_DATA    0x10	// kernel data
#define GD_USER_TEXT    0x18	// user text
#define GD_USER_DATA    0x20	// user data
#define GD_TSS          0x28	// Task segment selector

#define	KBASE	        0xf0000000
#define KSIZE           0x10000000

#define KVPT            0xefc00000


#define KTMP_TVPD_PAGE_OFFSET 0
#define KTMP_TVPT_PAGE_OFFSET 1
#define KTMP_TPAGE_PAGE_OFFSET 2
#define KTMP_PCS_PAGE_OFFSET 3
#define KTMP            0xef800000

#define KSTACK_TOP	    0xef800000
#define KSTACK_COUNT    250
#define KSTACK_BOT      0xef404000
#define KSTACK_SIZE     (3 * PAGE_SIZE)

// must ensure that
// KSTACK_COUNT * (KSTACK_SIZE + PAGE_SIZE) <= KSTACK_TOP - KSTACK_BOT

#define DYNINFO         0xef402000

#define UXSTACK_TOP     0xef401000
#define UXSTACK_SIZE    PAGE_SIZE
#define UXSTACK_BOT     0xef400000

/* 用户区的界线 */
#define ULIM		    0xef400000

// Same as VPT but read-only for users
#define UVPT            0xef000000
// Read-only copies of the global env structures
#define UENVS           0xeec00000
// Top of user-accessible VM
#define UTOP            0xeec00000
// Top of normal user stack
#define USTACK_TOP      0xeec00000

/* 可以供重新映射的地址上限 */
#define UMAP_TOP        0xeec00000
/* 用户堆的上限 */
#define UHEAP_TOP       0xee800000

/* 用户程序开始的地址 */
#define UPROG           0x00800000

/* EKOS USER CORE LIB */
#define ULIB            0x00000000

/* There a problem arise, since we use NULL pointer(0) to indicate a
 * meanless hole and to detect error, so the first page should not be
 * mapped. */


// At IOPHYSMEM (640K) there is a 384K hole for I/O.  From the kernel,
// IOPHYSMEM can be addressed at KERNBASE + IOPHYSMEM.  The hole ends
// at physical address EXTPHYSMEM.
#define IOPHYSMEM	0x0A0000
#define EXTPHYSMEM	0x100000

#ifndef __ASSEMBLER__

typedef uint32_t ptab_entry_t;
typedef uint32_t pdir_entry_t;

/* page clean stack */
#define PCS_PAGE_COUNT (PAGE_SIZE / sizeof(physaddr_t) - 3)

struct pcs_t
{
     physaddr_t last;
     uintptr_t  count;
     uintptr_t  total;
     physaddr_t data[PCS_PAGE_COUNT];
};

/* /\* 用来标示一个页表的标号, 同样假设生命周期中所有页表标号互不相同 *\/ */
/* extern volatile uint32_t vid; */

/*
 * Page descriptor structures, mapped at UPAGES.
 * Read/write to the kernel, read-only to user programs.
 *
 * Now the area is not to be allocated
 * 
 * Each Frame describes one physical page.
 * You can map a Page * to the corresponding physical address
 * with page2pa() in kern/pmap.h.
 */

struct frame_t {
     uint16_t ref_count;
     uint8_t  lock;
	 
	 /* 状态标记 */
	 uint8_t  flag;
	 
     struct frame_t *next;
};

#define FRAME_FREE   0
#define FRAME_USED   1
#define FRAME_SHARED 2

/* 初始内存信息块 */
struct memmap_t
{

     union
     {
	  struct { physaddr_t base_l; physaddr_t base_h; };
	  unsigned long long base;
     };

     union
     {
	  struct { physaddr_t end_l; physaddr_t end_h; };
	  unsigned long long end;
     };

     int32_t flag;

     char foo[4];		/* See MEMMAP_SIZE */
};

/* for 32-bit system */
#define MEMMAP_ADDR_OVERFLOW(addr)		\
     ((addr >> 32) > 0)

#define MEMMAP_BASE  ((void *)(KBASE + 0x1000))
#define MEMMAP_ENTRY ((void *)(KBASE + 0x1000 + sizeof(uint32_t)))

#endif /* !__ASSEMBLER__ */

#define MEMMAP_SIZE  24

#endif /* _EKOS_MEMLAYOUT_H_ */
